﻿using MarriageFertility.Extensions;
using MarriageFertility.Helpers;
using TaleWorlds.Engine;
using System.Collections.Generic;
using MarriageFertility.Texts;
using TaleWorlds.CampaignSystem;
using TaleWorlds.CampaignSystem.Actions;
using TaleWorlds.CampaignSystem.AgentOrigins;
using TaleWorlds.Core;
using TaleWorlds.Library;
using TaleWorlds.MountAndBlade;

namespace MarriageFertility.Missions
{
    public class SpouseBattleMissionMissionLogic : MissionLogic
    {
        public List<Agent> SpouseAgents;
        private Agent _winningSpouse;
        private bool _battleHasEnded;
        private Dictionary<string, Team> spouseTeams;
        public bool IsFinish;
        
        public override void AfterStart()
        {
            SpouseAgents = new List<Agent>();
            spouseTeams = new Dictionary<string, Team>();    
            SetupMission();
            SpawnSpouseAgents();
            IsFinish = true;
        }

        private void SetupMission()
        {
            Mission.SetMissionMode(MissionMode.Battle, true);
            InitializeTeams();
            _battleHasEnded = false;
        }

        
        
        private void InitializeTeams()
        {
            Mission.Teams.Add(BattleSideEnum.Attacker);
        }
        
        private void SetAgentTeam(Agent agent)
        {
            if (spouseTeams.ContainsKey(agent.Name))
            {
                agent.SetTeam(spouseTeams[agent.Name], false);
            }
            else
            {
                Team team = Mission.Teams.Add(BattleSideEnum.Attacker);
                agent.SetTeam(team, false);
                foreach (Team eachTeam in spouseTeams.Values)
                {
                    eachTeam.SetIsEnemyOf(team, true);
                }
                spouseTeams.Add(agent.Name, team);
            }
        }
        
        private void SpawnSpouseAgents()
        {
            if (Hero.MainHero.Spouse == null && Hero.MainHero.ExSpouses.Count <= 0)
            {
                Log.ErrorMessage(MessageText.NotEnoughSpouseText);
                return;
            }
            var spouses = Hero.MainHero.SpousesInParty();
            List<GameEntity> spawnPoints = MissionHelper.GetSpawnPoints(spouses.Count);
            InitFrames(spawnPoints, spouses);
        }

        private void InitFrames(List<GameEntity> spawnPoints, List<Hero> spouses)
        {
            if (spawnPoints == null || spawnPoints.Count == 0)
            {
                Log.ErrorMessage("Spawn points list is null or empty.");
                return;
            }

            if (spouses == null || spouses.Count == 0)
            {
                Log.ErrorMessage("Spouses list is null or empty.");
                return;
            }

            MatrixFrame globalFrame = spawnPoints[0].GetGlobalFrame();
            globalFrame.rotation.OrthonormalizeAccordingToForwardAndKeepUpAsZAxis();

            var player = SpawnPlayer(CharacterObject.PlayerCharacter, globalFrame);
            ProtectPlayer(player.Team);

            int spawnPointCount = spawnPoints.Count;

            for (int i = 0; i < spouses.Count; i++)
            {
                Hero spouse = spouses[i];
                if (spouse?.CharacterObject == null)
                {
                    Log.ErrorMessage($"Spouse at index {i} is null or has no CharacterObject.");
                    continue;
                }

                MatrixFrame frame = spawnPoints[i % spawnPointCount].GetGlobalFrame();
                Agent agent = MissionHelper.SpawnAgent(spouse.CharacterObject, frame, false, true, false);
                SetAgentTeam(agent);
                SpouseAgents.Add(agent);
            }
        }
        
        private Agent SpawnPlayer(CharacterObject character, MatrixFrame spawnFrame)
        {
            AgentBuildData agentBuildData = new AgentBuildData(character);
            agentBuildData.BodyProperties(character.GetBodyPropertiesMax());
            Team playerTeam = Mission.PlayerTeam;
            Mission mission = Mission;
            AgentBuildData agentBuildData2 = agentBuildData.Team(playerTeam).InitialPosition(spawnFrame.origin);
            Vec2 vec = spawnFrame.rotation.f.AsVec2;
            vec = vec.Normalized();
            Agent agent = mission.SpawnAgent(agentBuildData2.InitialDirection(vec).TroopOrigin(new SimpleAgentOrigin(character, -1, null, default(UniqueTroopDescriptor))), false);
            agent.FadeIn();
            agent.Controller = Agent.ControllerType.Player;
            agent.Health = Hero.MainHero.HitPoints;
            agent.HealthLimit = Hero.MainHero.MaxHitPoints;
            WieldInitialWeapons(agent);
            return agent;
        }

        private void ProtectPlayer(Team team)
        {
            foreach (Team eachTeam in spouseTeams.Values)
            {
                eachTeam.SetIsEnemyOf(team, false);
            }
        }
        
        public void WieldInitialWeapons(Agent agent, Agent.WeaponWieldActionType wieldActionType = Agent.WeaponWieldActionType.InstantAfterPickUp)
        {
            EquipmentIndex wieldedItemIndex = agent.GetWieldedItemIndex(Agent.HandIndex.MainHand);
            EquipmentIndex wieldedItemIndex2 = agent.GetWieldedItemIndex(Agent.HandIndex.OffHand);
            agent.SpawnEquipment.GetInitialWeaponIndicesToEquip(out wieldedItemIndex, out wieldedItemIndex2, out bool flag);
            if (wieldedItemIndex2 != EquipmentIndex.None)
            {
                agent.TryToWieldWeaponInSlot(wieldedItemIndex2, wieldActionType, true);
            }
            if (wieldedItemIndex != EquipmentIndex.None)
            {
                agent.TryToWieldWeaponInSlot(wieldedItemIndex, wieldActionType, true);
            }
        }
        
        public override void OnAgentRemoved(Agent affectedAgent, Agent affectorAgent, AgentState agentState, KillingBlow killingBlow)
        {
            if (SpouseAgents.Contains(affectedAgent))
            {
                SpouseAgents.Remove(affectedAgent);

                if (SpouseAgents.Count == 1)
                {
                    _winningSpouse = SpouseAgents[0];
                    EndBattle();
                }
            }
        }

        private void EndBattle()
        {
            _battleHasEnded = true;
            if (_winningSpouse != null)
            {
                MBInformationManager.AddQuickInformation(TournamentText.WinningSpouseText.SetTextVariable("hero", _winningSpouse.Name));
                Hero hero = _winningSpouse.GetHero();
                RelationHelper.SetSpouse(hero);
                ChangeRelationAction.ApplyRelationChangeBetweenHeroes(hero,Hero.MainHero, 5);
                _winningSpouse.SetWantsToYell();
                _winningSpouse.SetActionChannel(1, ActionIndexCache.Create("act_command"), true);
                _winningSpouse.MakeVoice(SkinVoiceManager.VoiceType.Yell, SkinVoiceManager.CombatVoiceNetworkPredictionType.NoPrediction);
            }
            else
            {
                MBInformationManager.AddQuickInformation(TournamentText.NoWinnerText);
            }
            MissionHelper.SetLeaveKey();
            MBInformationManager.AddQuickInformation(TournamentText.EndBattleText);
        }

        public override void OnMissionTick(float dt)
        {
            HandleInput();
            if (!_battleHasEnded && SpouseAgents.Count == 1)
            {
                EndBattle();
            }
        }

        private void HandleInput(){
 
               
            
        }
    }
}
